package com.dhcc.sds.busi.service.impl;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.dhcc.cdc.busi.dao.CdcLocationMapper;
import com.dhcc.cdc.busi.entity.CdcDictionaryEntity;
import com.dhcc.cdc.busi.entity.CdcEpisodeEntity;
import com.dhcc.cdc.busi.entity.CdcLocationEntity;
import com.dhcc.cdc.busi.service.ICdcDictionaryService;
import com.dhcc.cdc.sys.cache.config.CdcConfigCache;
import com.dhcc.cdc.sys.entity.ConfigurationEntity;
import com.dhcc.cdc.sys.entity.DictionaryEntity;
import com.dhcc.cdc.sys.service.IConfigurationService;
import com.dhcc.cdc.sys.service.IDictionaryService;
import com.dhcc.core.framework.util.CommonUtil;
import com.dhcc.core.framework.util.RedisUtil;
import com.dhcc.sdc.busi.entity.SdcBusiQcTriggeredEntity;
import com.dhcc.sdc.busi.entity.SdcQcEntity;
import com.dhcc.sdc.busi.service.ISdcHomeIndexService;
import com.dhcc.sds.base.entity.SdsQcentityEntity;
import com.dhcc.sds.base.service.ISdsCommonService;
import com.dhcc.sds.base.service.ISdsQcentityService;
import com.dhcc.sds.busi.dao.SdsQcincaseMapper;
import com.dhcc.sds.busi.entity.*;
import com.dhcc.sds.busi.service.*;
import com.dhcc.sds.busi.vo.AnalysisSdsPortalVo;
import com.dhcc.sds.util.DateUtil;
import com.dhcc.sds.util.StrUtil;


import com.googlecode.aviator.utils.ArrayHashMap;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @author 80572
 * @version 1.0
 * @date 2022/3/23 9:34
 */
@Service
public class AnalysisSdsPortalServiceImpl implements IAnalysisSdsPortalService {

    @Autowired
    private ISdsQcincaseOperlogService sdsQcincaseOperlogService;
    @Autowired
    private IConfigurationService configurationService;
    @Autowired
    private ISdsQcincaseService sdsQcincaseService;
    @Autowired
    private ISdsQcentityService sdsQcentityService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private IDictionaryService dictionaryService;
    @Autowired
    private ISdsQcincaseDataService sdsQcincaseDataService;
    @Autowired
    private ICdcDictionaryService cdcDictionaryService;
    @Autowired
    private ISdsDimDataService sdsDimDataService;
    @Autowired
    private ISdsDimAliasService sdsDimAliasService;
    @Autowired
    private ISdcHomeIndexService sdcHomeIndexService;
    @Autowired
    private ISdsCommonService sdsCommonService;
    @Autowired
    private SdsQcincaseMapper sdsQcincaseMapper;
    @Autowired
    private CdcLocationMapper cdcLocationMapper;

    double all = 1;
    Double cur =(double) 0;

    @Override
    public JSONObject selectMrlistCnt(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        //今日上报,本月上报,本年上报,累积上报
        List<Integer> upCount = sdsQcincaseOperlogService.selectPortalCount(params);
        caseObj.put("upCount", upCount);
        //待填报,待审核,待上报,退回报告
        // 单病种医生是否可以直接上报配置
        String formCheckType = CdcConfigCache.me().getValueByKey("SDS", "SDFormCheckType");
        params.put("formCheckType", formCheckType);
        List<Integer> incaseCount = sdsQcincaseService.selectPortalCount(params);
        caseObj.put("incaseCount", incaseCount);
        //7日未报,10日未报,30日未报,90日未报
        int donotRep7 = 0;
        int donotRep10 = 0;
        int donotRep30 = 0;
        int donotRep90 = 0;
        List<AnalysisSdsPortalVo> donotRep7List = new ArrayList<>();
        List<AnalysisSdsPortalVo> donotRep10List = new ArrayList<>();
        List<AnalysisSdsPortalVo> donotRep30List = new ArrayList<>();
        List<AnalysisSdsPortalVo> donotRep90List = new ArrayList<>();
        List<AnalysisSdsPortalVo> sdsPortalVoList = sdsQcincaseService.selectPortalMrlist(params);
        for (AnalysisSdsPortalVo sdsPortalVo : sdsPortalVoList){
            if (CommonUtil.notEquals(sdsPortalVo.getStatusDesc(), "Up") && CommonUtil.isNotEmpty(sdsPortalVo.getDisDate())) {
                int day = Math.toIntExact(DateUtil.getDateCompare(new Date(), sdsPortalVo.getDisDate(), "d"));
                if (day >= 7 && day < 10){
                    donotRep7++;
                    donotRep7List.add(sdsPortalVo);
                }else if (day >= 10 && day < 30){
                    donotRep10++;
                    donotRep10List.add(sdsPortalVo);
                }else if (day >= 30 && day < 90){
                    donotRep30++;
                    donotRep30List.add(sdsPortalVo);
                }else if (day >= 90){
                    donotRep90++;
                    donotRep90List.add(sdsPortalVo);
                }
            }
        }
        redisUtil.set("donotRep7", donotRep7List);
        redisUtil.set("donotRep10", donotRep10List);
        redisUtil.set("donotRep30", donotRep30List);
        redisUtil.set("donotRep90", donotRep90List);
        caseObj.put("donotRep7", donotRep7);
        caseObj.put("donotRep10", donotRep10);
        caseObj.put("donotRep30", donotRep30);
        caseObj.put("donotRep90", donotRep90);
        return caseObj;
    }

    @Override
    public JSONObject selectMainChart(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        DateTime nowDate = new DateTime();
        DateTime lastYearDate = DateUtil.getDateByYear(nowDate, -1);
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseOperlogService.selectMainChartData(nowDate, lastYearDate, params);
        caseObj.put("mainChart", analysisSdsPortalVoList);
        return caseObj;
    }

    @Override
    public JSONObject selectSysSumChart(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<Long> entityIds = sdsQcincaseService.selectEntity();
        all = entityIds.size();
        Map<String, AnalysisSdsPortalVo> calData = new HashMap<>();
        //单线程版
        /*for (Long entityId : entityIds){
            //每个病种取最近十个
            AnalysisSdsPortalVo analysisSdsPortalVo = sdsQcincaseService.selectCostsAndDays(entityId);
            if (StringUtils.isEmpty(analysisSdsPortalVo.getDescription())){
                continue;
            }
            String description = analysisSdsPortalVo.getDescription();
            switch (description){
                case "呼吸系统疾病/手术":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                case "神经系统疾病/手术":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                case "生殖系统疾病/手术":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                case "心血管系统疾病/手术":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                case "运动系统疾病/手术":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                case "肿瘤（手术治疗）":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                case "其他疾病/手术":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                default:
                    break;
            }
        }*/
        //多线程版
        ExecutorService analysisDataPools = Executors.newFixedThreadPool(10);//分析数据线程池
        CountDownLatch countDownLatch = new CountDownLatch(entityIds.size());//确定会启动10个线程任务
        for (Long entityId : entityIds){
            analysisDataPools.execute(new AnalysisData(entityId,params,calData,countDownLatch));
        }
        try {
            countDownLatch.await();//多线程运行结束前自旋等待
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
//        analysisDataPools.shutdown();

        //求平均值
        List<AnalysisSdsPortalVo> averageData = new ArrayList<>();
        DecimalFormat df = new DecimalFormat("0.00");
        for (String key : calData.keySet()){
            AnalysisSdsPortalVo analysisSdsPortalVo = calData.get(key);
            Double costs = analysisSdsPortalVo.getCosts();
            Integer days = analysisSdsPortalVo.getDays();
            Integer count = analysisSdsPortalVo.getCount();
            String averageDays = df.format((float)(days/count));
            //double averageCosts = costs/count;
            String averageCosts = "";
            if (!StringUtils.isEmpty(costs) && !StringUtils.isEmpty(count)){
                averageCosts = df.format(((costs) / count));
            }
            //String averageCosts = df.format(((costs) / count));
            AnalysisSdsPortalVo analysisSdsPortalVo1 = new AnalysisSdsPortalVo();
            analysisSdsPortalVo1.setDescription(key);
            analysisSdsPortalVo1.setAverageCosts(averageCosts);
            analysisSdsPortalVo1.setAverageDays(averageDays);
            averageData.add(analysisSdsPortalVo1);
        }
        caseObj.put("averageData", averageData);
        return caseObj;
    }

    @Override
    public JSONObject selectQCSumChart(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        //String qcTimeDimens = (String) params.get("qcTimeDimens");
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseOperlogService.selectQCSumChartData(params);
        caseObj.put("upEntitys", analysisSdsPortalVoList);
        return caseObj;
    }

    @Override
    public JSONObject selectLocSumChart(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        //String qcTimeDimens = (String) params.get("qcTimeDimens");
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseOperlogService.selectLocSumChartData(params);
        caseObj.put("upLoc", analysisSdsPortalVoList);
        return caseObj;
    }

    @Override
    public JSONObject selectDocSumChart(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        //String qcTimeDimens = (String) params.get("qcTimeDimens");
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseOperlogService.selectDocSumChartData(params);
        caseObj.put("upDoc", analysisSdsPortalVoList);
        return caseObj;
    }

    @Override
    public JSONObject selectARatioChart(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseService.selectARatioChartData(params);
        //去除提取率为0的病种
        List<AnalysisSdsPortalVo> res = new ArrayList<>();
        DecimalFormat df = new DecimalFormat("0.00");
        for (AnalysisSdsPortalVo analysisSdsPortalVo : analysisSdsPortalVoList){
            String description = analysisSdsPortalVo.getDescription();
            if (!StringUtils.isEmpty(analysisSdsPortalVo.getaCount())){
                Integer aCount = analysisSdsPortalVo.getaCount();
                Integer nCount = analysisSdsPortalVo.getnCount();
                String aRatio = df.format(((double) (aCount) / (aCount + nCount)) * 100);
                analysisSdsPortalVo.setaRatio(aRatio);
                res.add(analysisSdsPortalVo);
            }
        }
        caseObj.put("aRatioData", res);
        return caseObj;
    }

    @Override
    public JSONObject selectUseTimeChart(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<AnalysisSdsPortalVo> useTimeData = new ArrayList<>();
        List<Long> entityIds = sdsQcincaseService.selectEntity();
        List<String> status = Arrays.asList("Submit", "Check", "Up");
        for (Long entityId : entityIds){
            Long sumMin = 0l;
            List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseService.selectByStatus(entityId, status, params);
            if (analysisSdsPortalVoList.isEmpty()){
                continue;
            }
            String s = analysisSdsPortalVoList.get(0).getDescription();
            String c = analysisSdsPortalVoList.get(0).getCode();
            List<Long> useTime = new ArrayList<>();
            for (AnalysisSdsPortalVo analysisSdsPortalVo : analysisSdsPortalVoList){
                //统计病种近10份有效报告的填报用时
                Long min = this.handUseTime(analysisSdsPortalVo.getId());
                useTime.add(min);
                sumMin += min;
            }
            //Long avgUseTime = sumMin/analysisSdsPortalVoList.size();
            String avgUseTime = StrUtil.deciFormatLong(sumMin, analysisSdsPortalVoList.size());
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            analysisSdsPortalVo.setDescription(s);
            analysisSdsPortalVo.setCode(c);
            analysisSdsPortalVo.setAvgUseTime(avgUseTime);
            analysisSdsPortalVo.setUseTime(useTime);
            useTimeData.add(analysisSdsPortalVo);
        }
        caseObj.put("useTimeData", useTimeData);
        return caseObj;
    }

    @Override
    public List<AnalysisSdsPortalVo> selectMrlistCntDetails(String idName, List<String> deptIds) {
        List<AnalysisSdsPortalVo> sdsPortalVoList = new ArrayList<>();
        if (Objects.equals("todayRep", idName) || Objects.equals("monthRep", idName)
                || Objects.equals("yearRep", idName) || Objects.equals("totalRep", idName)){
            //sdsPortalVoList = sdsQcincaseOperlogService.selectPortalCountDetails(idName, deptIds);
            List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseOperlogService.selectPortalCountDetailsList(idName, deptIds);
            sdsPortalVoList = this.handleMrlistCntDetails(analysisSdsPortalVoList);
        }else if (Objects.equals("readyRep", idName) || Objects.equals("readyCheck", idName)
                || Objects.equals("readyUp", idName) || Objects.equals("back", idName)){
            // 单病种医生是否可以直接上报配置
            String formCheckType = CdcConfigCache.me().getValueByKey("SDS", "SDFormCheckType");
            //sdsPortalVoList = sdsQcincaseService.selectPortalCountDetails(formCheckType, idName, deptIds);
            List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseService.selectPortalCountDetailsList(formCheckType, idName, deptIds);
            sdsPortalVoList = this.handleMrlistCntDetails(analysisSdsPortalVoList);
        }else if (Objects.equals("donotRep7", idName) || Objects.equals("donotRep10", idName)
                || Objects.equals("donotRep30", idName) || Objects.equals("donotRep90", idName)){
            if (CommonUtil.isNotEmpty(redisUtil.get(idName))){
                String s = redisUtil.get(idName);
                //Object parse = JSON.parse(s);
                List<AnalysisSdsPortalVo> analysisSdsPortalVoList1 = new ArrayList<>(JSONArray.parseArray(s, AnalysisSdsPortalVo.class));
                sdsPortalVoList = this.handleMrlistCntDetails(analysisSdsPortalVoList1);

            }
            //清空redis缓存
            //redisUtil.clean();
        }
        return sdsPortalVoList;
    }

    @Override
    public List<AnalysisSdsPortalVo> selectMrInfoByIDs(Map<String, Object> params) {
        String incaseIds = (String) params.get("incaseIds");
        String[] split = incaseIds.split(",");
        List<Long> ids = new ArrayList<>();
        for (String s : split){
            ids.add(Long.parseLong(s));
        }
        List<AnalysisSdsPortalVo> analysisSdsPortalVos = sdsQcincaseService.selectMrInfoByIDs(ids);
        /*for (AnalysisSdsPortalVo analysisSdsPortalVo : analysisSdsPortalVos){
            DictionaryEntity dictionaryEntity = dictionaryService.queryByTypeCodeAndCode("SDS", "SDQCMrStatus", analysisSdsPortalVo.getStatusCode());
            analysisSdsPortalVo.setStatusDesc(dictionaryEntity.getDescription());
        }*/
        return analysisSdsPortalVos;
    }

    @Override
    public List<AnalysisSdsPortalVo> selectByCondition(Map<String, Object> params) {
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList;
        String dateType = (String) params.get("aDateType"); //日期类型
        String idName = (String) params.get("idName");
        //状态
        String status = "";
        List<String> statusList = new ArrayList<>();
        if (!StringUtils.isEmpty(params.get("aStatus"))){
            status = (String) params.get("aStatus");
            String[] split = status.split(",");
            statusList = Arrays.asList(split);
        }
        //如果日期类型是上报日期
        if (Objects.equals("UpQC", dateType)){
            //如果要查询的状态是up或者空
            if (status.contains("Up") || StringUtils.isEmpty(status)){

                //analysisSdsPortalVoList = sdsQcincaseOperlogService.selectByCondition(params);
                List<AnalysisSdsPortalVo> sdsPortalVoList = sdsQcincaseOperlogService.selectByConditionList(params);

                if (Objects.equals("QCSumMore", idName)){
                    for (AnalysisSdsPortalVo sdsPortalVo : sdsPortalVoList){
                        sdsPortalVo.setCode(sdsPortalVo.getCode1());
                        sdsPortalVo.setDescription(sdsPortalVo.getDescription1());
                    }
                }else if (Objects.equals("LocSumMore", idName)){
                    for (AnalysisSdsPortalVo sdsPortalVo : sdsPortalVoList){
                        sdsPortalVo.setCode(sdsPortalVo.getCode2());
                        sdsPortalVo.setDescription(sdsPortalVo.getDescription2());
                    }
                }else if (Objects.equals("DocSumMore", idName)){
                    for (AnalysisSdsPortalVo sdsPortalVo : sdsPortalVoList){
                        sdsPortalVo.setCode(sdsPortalVo.getCode3());
                        sdsPortalVo.setDescription(sdsPortalVo.getDescription3());
                    }
                }else {
                    for (AnalysisSdsPortalVo sdsPortalVo : sdsPortalVoList){
                        sdsPortalVo.setCode(sdsPortalVo.getCode1());
                        sdsPortalVo.setDescription(sdsPortalVo.getDescription1());
                    }
                }
                analysisSdsPortalVoList = this.handleMrlistCntDetails(sdsPortalVoList);
            }else {
                //上报日期状态不为上报状态
                analysisSdsPortalVoList = null;
            }

        }else {
            //日期类型是出院日期
            //analysisSdsPortalVoList = sdsQcincaseService.selectByCondition(params,statusList);
            List<AnalysisSdsPortalVo> sdsPortalVoList = sdsQcincaseService.selectByConditionList(params,statusList);
            if (Objects.equals("QCSumMore", idName)){
                for (AnalysisSdsPortalVo sdsPortalVo : sdsPortalVoList){
                    sdsPortalVo.setCode(sdsPortalVo.getCode1());
                    sdsPortalVo.setDescription(sdsPortalVo.getDescription1());
                }
            }else if (Objects.equals("LocSumMore", idName)){
                for (AnalysisSdsPortalVo sdsPortalVo : sdsPortalVoList){
                    sdsPortalVo.setCode(sdsPortalVo.getCode2());
                    sdsPortalVo.setDescription(sdsPortalVo.getDescription2());
                }
            }else if (Objects.equals("DocSumMore", idName)){
                for (AnalysisSdsPortalVo sdsPortalVo : sdsPortalVoList){
                    sdsPortalVo.setCode(sdsPortalVo.getCode3());
                    sdsPortalVo.setDescription(sdsPortalVo.getDescription3());
                }
            }else {
                for (AnalysisSdsPortalVo sdsPortalVo : sdsPortalVoList){
                    sdsPortalVo.setCode(sdsPortalVo.getCode1());
                    sdsPortalVo.setDescription(sdsPortalVo.getDescription1());
                }
            }
            analysisSdsPortalVoList = this.handleMrlistCntDetails(sdsPortalVoList);
        }
        return analysisSdsPortalVoList;
    }

    @Override
    public List<AnalysisSdsPortalVo> selectSumChartData(String idName, Map<String, Object> params) {
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = new ArrayList<>();
        if (Objects.equals("QCSumMore", idName)){
            List<AnalysisSdsPortalVo> sdsPortalVoList = sdsQcincaseOperlogService.selectQCSumChartDataList(params);
            analysisSdsPortalVoList = this.handleMrlistCntDetails(sdsPortalVoList);
        }else if (Objects.equals("LocSumMore", idName)){
            List<AnalysisSdsPortalVo> sdsPortalVoList = sdsQcincaseOperlogService.selectLocSumChartDataList(params);
            analysisSdsPortalVoList = this.handleMrlistCntDetails(sdsPortalVoList);
        }else if (Objects.equals("DocSumMore", idName)){
            List<AnalysisSdsPortalVo> sdsPortalVoList = sdsQcincaseOperlogService.selectDocSumChartDataList(params);
            analysisSdsPortalVoList = this.handleMrlistCntDetails(sdsPortalVoList);
        }
        return analysisSdsPortalVoList;
    }

    @Override
    public JSONObject buildRepInfo(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<SdsQcincaseDataEntity> sdsQcincaseDataEntities = new ArrayList<>();
        //就诊类型:门诊
        CdcDictionaryEntity admType = cdcDictionaryService.queryByTypeCodeAndCode("PatData", "bus_adm_type", "O");
        //获取当天上报数据
        Date date = new Date();
        String sDate = com.dhcc.core.framework.util.DateUtil.formatDate(date, "yyyy-MM-dd");
        /*sdsQcincaseDataEntities  = sdsQcincaseDataService.selectList(new EntityWrapper<SdsQcincaseDataEntity>()
                .eq("upload_date", sDate));*/
        sdsQcincaseDataEntities = sdsQcincaseDataService.selectByUploadDateAndUserLinkDepts(sDate, params);
        int todayRep = 0;
        int todayOPRep = 0;
        int todayIPRep = 0;
        for (SdsQcincaseDataEntity sdsQcincaseDataEntity : sdsQcincaseDataEntities){
            todayRep++;
            if (Objects.equals(admType.getId(), sdsQcincaseDataEntity.getAdmType())){
                todayOPRep++;
            }
        }
        todayIPRep = todayRep - todayOPRep;
        //获取今日上报数据的环比 preDayRepRatio
        int preDayRep = 0;
        String preDayRepRatio = "-";
        DateTime dateYesterday = cn.hutool.core.date.DateUtil.offsetDay(date, -1);
        String sYesterday = com.dhcc.core.framework.util.DateUtil.formatDate(dateYesterday, "yyyy-MM-dd");
        /*sdsQcincaseDataEntities  = sdsQcincaseDataService.selectList(new EntityWrapper<SdsQcincaseDataEntity>()
                .eq("upload_date", sYesterday));*/
        sdsQcincaseDataEntities = sdsQcincaseDataService.selectByUploadDateAndUserLinkDepts(sYesterday, params);
        if (null != sdsQcincaseDataEntities){
            preDayRep = sdsQcincaseDataEntities.size();
        }
        if (preDayRep > 0){
            DecimalFormat df = new DecimalFormat("0.00");
            preDayRepRatio = df.format(((double)(todayRep-preDayRep)/preDayRep)*100) + "%";
        }
        //获取今日上报同比数据 overDayRep
        int overDayRep = 0;
        String overDayRepRatio = "-";
        int currentYear = cn.hutool.core.date.DateUtil.year(date);
        int currentQuarter = cn.hutool.core.date.DateUtil.quarter(date);
        int currentMonth = cn.hutool.core.date.DateUtil.month(date) + 1;
        String format = cn.hutool.core.date.DateUtil.format(date, "yyyy-MM-dd");
        DateTime lastYearToday = cn.hutool.core.date.DateUtil.parse((currentYear - 1) + format.substring(4, 10), "yyyy-MM-dd");
        String sLastYearToday = com.dhcc.core.framework.util.DateUtil.formatDate(lastYearToday, "yyyy-MM-dd");
        /*sdsQcincaseDataEntities  = sdsQcincaseDataService.selectList(new EntityWrapper<SdsQcincaseDataEntity>()
                .eq("upload_date", sLastYearToday));*/
        sdsQcincaseDataEntities = sdsQcincaseDataService.selectByUploadDateAndUserLinkDepts(sLastYearToday, params);
        if (null != sdsQcincaseDataEntities){
            overDayRep = sdsQcincaseDataEntities.size();
        }
        if (overDayRep > 0){
            DecimalFormat df = new DecimalFormat("0.00");
            overDayRepRatio = df.format(((double)(todayRep-overDayRep)/overDayRep)*100) + "%";
        }
        //获取月份级别的上报数据
        Wrapper dimWpr = new EntityWrapper<SdsDimDataEntity>()
                .eq("dim_type", "UpLoadDate")
                .eq("mr_status", "Up");
        // 如果用院区管理员角色，只查询本院区的dim数据
        if (CommonUtil.isNotEmpty(params.get("userLinkHospId"))) {
            dimWpr.eq("dim_hosp", params.get("userLinkHospId"));
        }
        List<SdsDimDataEntity> sdsDimDataEntities = sdsDimDataService.selectList(dimWpr);
        int totalRep = 0;
        int yearRep = 0;
        int quarterRep = 0;
        int monthRep = 0;
        int preMonthRep = 0;
        int overMonthRep = 0;
        int preQuarterRep = 0;
        int overQuarterRep = 0;
        int preYearRep = 0;
        int totalOPRep = 0;
        int yearOPRep = 0;
        int monthOPRep = 0;
        List<Long> userLinkDepts = (List<Long>) params.get("userLinkDepts");
        for (SdsDimDataEntity sdsDimDataEntity : sdsDimDataEntities){
            int yearRepFlg = 0;
            int quarterFlg = 0;
            int monthRepFlg = 0;
            int repCount = 0;
            repCount = sdsDimDataEntity.getMrCount();
            totalRep = totalRep + repCount;
            if (Objects.equals(currentYear, sdsDimDataEntity.getDimYear())){
                yearRepFlg = 1;
                yearRep = yearRep + repCount;

                if (Objects.equals(currentMonth, sdsDimDataEntity.getDimMonth())){
                    monthRepFlg = 1;
                    monthRep = monthRep + repCount;
                }

                if ((sdsDimDataEntity.getDimMonth()+2)/3 == currentQuarter) {
                    quarterFlg = 1;
                    quarterRep = quarterRep + repCount;
                }

            }
            //月同比 环比   年同比计算
            if (Objects.equals((sdsDimDataEntity.getDimYear()*12 + sdsDimDataEntity.getDimMonth()), (currentYear*12 + currentMonth - 1))){
                preMonthRep = preMonthRep + repCount;
            }
            if (Objects.equals((sdsDimDataEntity.getDimYear()*12 + sdsDimDataEntity.getDimMonth()), (currentYear*12 + currentMonth - 12))){
                overMonthRep = overMonthRep + repCount;
            }
            //季同比 环比
            if (Objects.equals((sdsDimDataEntity.getDimYear()*4 + ((sdsDimDataEntity.getDimMonth()+2)/3)), (currentYear*4 + ((currentMonth+2)/3) - 1))){
                preQuarterRep = preQuarterRep + repCount;
            }
            if (Objects.equals((sdsDimDataEntity.getDimYear()*4 + ((sdsDimDataEntity.getDimMonth()+2)/3)), (currentYear*4 + ((currentMonth+2)/3) - 5))){
                overQuarterRep = overQuarterRep + repCount;
            }
            //年同比
            if (Objects.equals(sdsDimDataEntity.getDimYear(), currentYear-1)){
                preYearRep = preYearRep + repCount;
            }
            //计算门诊病种上报情况
            List<SdsQcincaseEntity> sdsQcincaseEntities = sdsQcincaseService.selectOPByDimData(sdsDimDataEntity.getId(), admType.getId());
            if (null != sdsQcincaseEntities){
                if (Objects.equals(1, yearRepFlg)){
                    yearOPRep = yearOPRep + sdsQcincaseEntities.size();
                }
                if (Objects.equals(1, monthRepFlg)){
                    monthOPRep = monthOPRep + sdsQcincaseEntities.size();
                }
                totalOPRep = totalOPRep + sdsQcincaseEntities.size();
            }
        }
        int monthIPRep = monthRep - monthOPRep;
        int yearIPRep = yearRep - yearOPRep;
        int totalIPRep = totalRep - totalOPRep;
        //同比 环比  门诊 住院上报数据
        String overMonthRepRatio = "-";
        String overQuarterRepRatio = "-";
        String preMonthRepRatio = "-";
        String preQuarterRepRatio = "-";
        String preYearRepRatio = "-";
        if (overMonthRep > 0){
            DecimalFormat df = new DecimalFormat("0.00");
            overMonthRepRatio = df.format(((double)(monthRep-overMonthRep)/overMonthRep)*100) + "%";
        }
        if (preMonthRep > 0){
            DecimalFormat df = new DecimalFormat("0.00");
            preMonthRepRatio = df.format(((double)(monthRep-preMonthRep)/preMonthRep)*100) + "%";
        }
        if (overQuarterRep > 0){
            DecimalFormat df = new DecimalFormat("0.00");
            overQuarterRepRatio = df.format(((double)(quarterRep-overQuarterRep)/overQuarterRep)*100) + "%";
        }
        if (preQuarterRep > 0){
            DecimalFormat df = new DecimalFormat("0.00");
            preQuarterRepRatio = df.format(((double)(quarterRep-preQuarterRep)/preQuarterRep)*100) + "%";
        }
        if (preYearRep > 0){
            DecimalFormat df = new DecimalFormat("0.00");
            overMonthRepRatio = df.format(((double)(yearRep-preYearRep)/preYearRep)*100) + "%";
        }

        //迟报数
        int delayReport=sdsQcincaseMapper.getDelayReportCount(params);

        //获取已开展病种
        int repCount = sdsQcincaseDataService.selectRepCount(params);
        caseObj.put("disHasDev",repCount);


        caseObj.put("todayRep", todayRep);
        caseObj.put("monthRep", monthRep);
        caseObj.put("quarterRep", quarterRep);
        caseObj.put("yearRep", yearRep);
        caseObj.put("totalRep", totalRep);

        caseObj.put("todayOPRep", todayOPRep);
        caseObj.put("todayIPRep", todayIPRep);
        caseObj.put("preDayRepRatio", preDayRepRatio);
        caseObj.put("overDayRepRatio", overDayRepRatio);

        caseObj.put("monthOPRep", monthOPRep);
        caseObj.put("monthIPRep", monthIPRep);
        caseObj.put("preMonthRepRatio", preMonthRepRatio);
        caseObj.put("overMonthRepRatio", overMonthRepRatio);

        caseObj.put("preQuarterRepRatio", preQuarterRepRatio);
        caseObj.put("overQuarterRepRatio", overQuarterRepRatio);

        caseObj.put("yearOPRep", yearOPRep);
        caseObj.put("yearIPRep", yearIPRep);
        caseObj.put("preYearRepRatio", preYearRepRatio);
        caseObj.put("totalOPRep", totalOPRep);
        caseObj.put("totalIPRep", totalIPRep);
        caseObj.put("delayReport",delayReport);
        return caseObj;
    }

    @Override
    public JSONObject selectNearYearRep(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        Date date = new Date();
        int endYear = cn.hutool.core.date.DateUtil.year(date);
        int endMonth = cn.hutool.core.date.DateUtil.month(date) + 1;
        int startYear;
        int startMonth;
        //如果当前是12月份，那么则查询当前一年的，如果是1-11月份，则查询去年次月到当前月份的
        if (Objects.equals(12, endMonth)){
            startYear = endYear;
            startMonth = 1;
        }else {
            startYear = endYear - 1;
            startMonth = endMonth + 1;
        }
        int endMonthCnt = endYear*100 + endMonth;
        int startMonthCnt = startYear*100 + startMonth;
        List<SdsDimDataEntity> list = sdsDimDataService.selectNearYearRep(startMonthCnt, endMonthCnt, "Up", "UpLoadDate", params.get("userLinkHospId").toString());
        Map<String, Integer> rep = new LinkedHashMap<>();
        for (SdsDimDataEntity sdsDimDataEntity : list){
            String key = sdsDimDataEntity.getDimYear() + "年" + sdsDimDataEntity.getDimMonth() + "月";
            if (StringUtils.isEmpty(rep.get(key))){
                rep.put(key, sdsDimDataEntity.getMrCount());
            }else {
                Integer value = rep.get(key);
                rep.put(key, value + sdsDimDataEntity.getMrCount());
            }
        }
        caseObj.put("mainChart", rep);
        return caseObj;
    }

    @Override
    public JSONObject selectQCOpenSum(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        Long entityTypeId = sdsCommonService.getDictId("QcentityType","Up");
        List<SdsQcentityEntity> sdsQcentityEntities = sdsQcentityService.selectList(new EntityWrapper<SdsQcentityEntity>()
                .eq("entity_type_id",entityTypeId).ne("is_active", 0));
        int repCount = sdsQcincaseDataService.selectRepCount(params);
        int NoRepCount = sdsQcentityEntities.size() - repCount;
        Map<String, Integer> map = new HashMap<>();
        map.put("已开展病种", repCount);
        map.put("未开展病种", NoRepCount);
        caseObj.put("openSum", map);
        return caseObj;
    }

    @Override
    public JSONObject selectQCSysInfo(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        //每个病种默认统计10份病历
        int aStaCnt = 10;
        Map<String, BigDecimal> fee = new HashMap<>();
        Map<String, Integer> days = new HashMap<>();
        Map<String, Integer> cnt = new HashMap<>();
        //方法2：200ms
        List<DictionaryEntity> entityCat = dictionaryService.queryByTypeCode("SDS", "EntityCat");
        a:for (DictionaryEntity dictionaryEntity : entityCat){
            int aCount = 0;
            List<SdsDimDataEntity> sdsDimDataEntities = sdsDimDataService.selectOrderByType("UpLoadDate", dictionaryEntity.getDescription());
            if (StringUtils.isEmpty(sdsDimDataEntities)){
                continue a;
            }
            b:for (SdsDimDataEntity sdsDimDataEntity : sdsDimDataEntities){
                aCount = aCount + sdsDimDataEntity.getMrCount();
                AnalysisSdsPortalVo analysisSdsPortalVo = sdsQcincaseDataService.selectCostAndDayByDimData(sdsDimDataEntity.getId());
                //费用
                if (StringUtils.isEmpty(fee.get(dictionaryEntity.getDescription()))){
                    fee.put(dictionaryEntity.getDescription(), analysisSdsPortalVo.getHospCost());
                    cnt.put(dictionaryEntity.getDescription(), aCount);
                }else {
                    BigDecimal bigDecimal = fee.get(dictionaryEntity.getDescription());
                    fee.put(dictionaryEntity.getDescription(), bigDecimal.add(analysisSdsPortalVo.getHospCost()));
                    cnt.put(dictionaryEntity.getDescription(), cnt.get(dictionaryEntity.getDescription()) + aCount);
                }
                //住院日
                if (StringUtils.isEmpty(days.get(dictionaryEntity.getDescription()))){
                    days.put(dictionaryEntity.getDescription(), analysisSdsPortalVo.getDays());
                }else {
                    int d = days.get(dictionaryEntity.getDescription());
                    days.put(dictionaryEntity.getDescription(), d + analysisSdsPortalVo.getDays());
                }

                if (aCount > aStaCnt){
                    break b;
                }
            }
        }

        //输出相关系统疾病的费用与住院日
        List<AnalysisSdsPortalVo> sdsPortalFee = new ArrayList<>();
        List<AnalysisSdsPortalVo> sdsPortalDay = new ArrayList<>();

        for (String s : fee.keySet()){
            BigDecimal b = fee.get(s);
            BigDecimal c = new BigDecimal(String.valueOf(cnt.get(s)));
            BigDecimal bigDecimal = b.divide(c, 2, BigDecimal.ROUND_HALF_UP);
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            analysisSdsPortalVo.setDescription(s);
            analysisSdsPortalVo.setAverageHospCosts(bigDecimal);
            sdsPortalFee.add(analysisSdsPortalVo);
        }
        for (String s : days.keySet()){
            int d = days.get(s);
            DecimalFormat df = new DecimalFormat("0.00");
            String averageDays = df.format((float)(d/cnt.get(s)));
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            analysisSdsPortalVo.setDescription(s);
            analysisSdsPortalVo.setAverageDays(averageDays);
            sdsPortalDay.add(analysisSdsPortalVo);
        }


        //方法1：300ms
       /* List<SdsQcentityEntity> sdsQcentityEntities = sdsQcentityService.selectList(null);
        for (SdsQcentityEntity sdsQcentityEntity : sdsQcentityEntities){
            *//*DictionaryEntity dictionaryEntity = dictionaryService.selectById(sdsQcentityEntity.getEntityCatId());
            String entityCat = dictionaryEntity.getDescription();*//*
            AnalysisSdsPortalVo sdsPortal = sdsDimDataService.selectFeeAndDaysByEntityId(sdsQcentityEntity.getId());
            if (StringUtils.isEmpty(sdsPortal.getDescription())){
                continue;
            }
            //fee
            if (StringUtils.isEmpty(fees.get(sdsPortal.getDescription()))){
                fees.put(sdsPortal.getDescription(), sdsPortal.getHospCost());
                count.put(sdsPortal.getDescription(), sdsPortal.getCount());
            }else {
                BigDecimal b = fees.get(sdsPortal.getDescription());
                int c = count.get(sdsPortal.getDescription());
                fees.put(sdsPortal.getDescription(), b.add(sdsPortal.getHospCost()));
                count.put(sdsPortal.getDescription(), c + sdsPortal.getCount());
            }
            //day
            if (StringUtils.isEmpty(days.get(sdsPortal.getDescription()))){
                days.put(sdsPortal.getDescription(), sdsPortal.getDays());
            }else {
                int d = days.get(sdsPortal.getDescription());
                days.put(sdsPortal.getDescription(), d + sdsPortal.getDays());
            }
        }

        List<AnalysisSdsPortalVo> sdsPortalFee = new ArrayList<>();
        List<AnalysisSdsPortalVo> sdsPortalDay = new ArrayList<>();
        //输出相关系统疾病的费用与住院日
        for (String s : fees.keySet()){
            BigDecimal b = fees.get(s);
            BigDecimal c = new BigDecimal(String.valueOf(count.get(s)));
            BigDecimal bigDecimal = b.divide(c).setScale(2, BigDecimal.ROUND_HALF_UP);
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            analysisSdsPortalVo.setDescription(s);
            analysisSdsPortalVo.setAverageHospCosts(bigDecimal);
            sdsPortalFee.add(analysisSdsPortalVo);
        }
        for (String s : days.keySet()){
            int d = days.get(s);
            DecimalFormat df = new DecimalFormat("0.00");
            String averageDays = df.format((float)(d/count.get(s)));
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            analysisSdsPortalVo.setDescription(s);
            analysisSdsPortalVo.setAverageDays(averageDays);
            sdsPortalDay.add(analysisSdsPortalVo);
        }*/

        caseObj.put("fees", sdsPortalFee);
        caseObj.put("days", sdsPortalDay);
        return caseObj;
    }

    @Override
    public JSONObject selectQCUpLoadData(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseDataService.selectQCUpLoadData(params);
        caseObj.put("upEntitys", analysisSdsPortalVoList);
        return caseObj;
    }

    @Override
    public JSONObject selectLocUpLoadData(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseDataService.selectLocUpLoadData(params);
        caseObj.put("upLoc", analysisSdsPortalVoList);
        return caseObj;
    }

    @Override
    public JSONObject selectDocUpLoadData(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseDataService.selectDocUpLoadData(params);
        caseObj.put("upDoc", analysisSdsPortalVoList);
        return caseObj;
    }

    public JSONObject selectQCARatio(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        /*List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseDataService.selectARatio();
        for (AnalysisSdsPortalVo sdsPortalVo : analysisSdsPortalVoList){
            String s = sdsPortalVo.getaRatio();
            String[] split = s.split(";");
            //过滤采集率为零的病种
            if (Objects.equals(0, split[0])){
                continue;
            }
            String r = split[2];
            sdsPortalVo.setaRatio(r.substring(0,r.length() - 1));
        }*/
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = new ArrayList<>();
        List<Long> entityIds = sdsQcincaseService.selectEntity();
        for (Long entityId: entityIds){
            //统计病种最新十条数据
            params.put("entityId", entityId);
            List<AnalysisSdsPortalVo> analysisSdsPortalVos = sdsQcincaseDataService.selectARatio(params);
            int i = 0;
            Double rate = (double) 0;
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            for (AnalysisSdsPortalVo vo : analysisSdsPortalVos) {
                String s = vo.getaRatio();
                String[] split = s.split(";");
                //过滤采集率为零的病种
                if (Objects.equals("0", split[0])){
                    continue;
                }
                BeanUtils.copyProperties(vo, analysisSdsPortalVo);
                Double r = Double.valueOf(split[2].substring(0,split[2].length() - 1));
                rate += r;
                i++;
            }
            if (i!=0) {
                analysisSdsPortalVo.setaRatio(String.format("%.2f",rate/i));
                analysisSdsPortalVoList.add(analysisSdsPortalVo);
            }
        }
        caseObj.put("aRatioData", analysisSdsPortalVoList);
        return caseObj;
    }

    @Override
    public List<AnalysisSdsPortalVo> selectPatDetail(Map<String, Object> params) {
        String qcidStr = (String) params.get("qcid");
        String qcDisName = (String) params.get("qcDisName");
        Long qcid = Long.valueOf(qcidStr);
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = new ArrayList<>();
        List<CdcEpisodeEntity> cdcEpisodeEntities = sdsQcincaseDataService.selectPatientDetail(qcid);
        for(CdcEpisodeEntity cdcEpisodeEntity : cdcEpisodeEntities) {
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            analysisSdsPortalVo.setId(cdcEpisodeEntity.getId());
            analysisSdsPortalVo.setPatName(cdcEpisodeEntity.getName());
            analysisSdsPortalVo.setMrNo(cdcEpisodeEntity.getMrNum());
            analysisSdsPortalVo.setDeptName(cdcEpisodeEntity.getAdmLocDesc());
            analysisSdsPortalVo.setDocName(cdcEpisodeEntity.getAdmDoctorName());
            analysisSdsPortalVo.setDescription(qcDisName);
            analysisSdsPortalVo.setAdmDate(cdcEpisodeEntity.getAdmDate());
            analysisSdsPortalVo.setDisDate(cdcEpisodeEntity.getDishDate());
            analysisSdsPortalVoList.add(analysisSdsPortalVo);
        }

        return analysisSdsPortalVoList;
    }

    @Override
    public JSONObject selectdevlist(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseDataService.selectdevlist(params);
        caseObj.put("declist",analysisSdsPortalVoList);
        return caseObj;
    }

    /**
     * @Description: 查询医生质控触发数据详情
     * @return: JSONObject
     * @author: yanghangwei
     * @date:2023年8月10日 下午13:40:50
     */
    @Override
    public  List<AnalysisSdsPortalVo> selectAllDoctorData(Map<String, Object> params) {
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = new ArrayList<>();
        List<Map<String, Object>> doctorData = sdcHomeIndexService.selectAllDoctorData(params);
        for (Map<String, Object> data : doctorData) {
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            analysisSdsPortalVo.setDocName((String) data.get("doctorName"));
            analysisSdsPortalVo.setDrgName((String) data.get("drgName"));
            analysisSdsPortalVo.setInCaseCount(((Long) data.get("inCaseNum")).intValue());
            analysisSdsPortalVo.setQcCaseCount(((Long) data.get("qcCaseNum")).intValue());
            analysisSdsPortalVo.setQcCaseTri(((Long) data.get("qcCaseTri")).intValue());
            analysisSdsPortalVo.setAverageDays(((BigDecimal) data.get("avgAdmDays")).toString());
            analysisSdsPortalVoList.add(analysisSdsPortalVo);
        }
        return analysisSdsPortalVoList;
    }


    @Override
    public JSONObject selectQCCategory(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = new ArrayList<>();
        List<SdcBusiQcTriggeredEntity> sdcBusiQcTriggeredEntities = sdsQcincaseDataService.selectQCCategory(params);
        for (SdcBusiQcTriggeredEntity sdcBusiQcTriggeredEntity : sdcBusiQcTriggeredEntities){
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            //添加病种相关的数据
            analysisSdsPortalVo.setPatCount(sdcBusiQcTriggeredEntity.getPatcount());
            analysisSdsPortalVo.setIds(String.valueOf(sdcBusiQcTriggeredEntity.getQcId()));
            analysisSdsPortalVo.setDescription(sdcBusiQcTriggeredEntity.getDetail());
            analysisSdsPortalVo.setPatName(sdcBusiQcTriggeredEntity.getAbbrev());
            analysisSdsPortalVo.setCount(sdcBusiQcTriggeredEntity.getCount());
            analysisSdsPortalVoList.add(analysisSdsPortalVo);
        }
        caseObj.put("qcCategory", analysisSdsPortalVoList);
        return caseObj;
    }

    @Override
    public JSONObject selectQCCategoryByCondition(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = new ArrayList<>();
        List<SdcBusiQcTriggeredEntity> sdcBusiQcTriggeredEntities = sdsQcincaseDataService.selectQCCategoryByCondition(params);
        for (SdcBusiQcTriggeredEntity sdcBusiQcTriggeredEntity : sdcBusiQcTriggeredEntities){
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            //添加病种相关的数据
            analysisSdsPortalVo.setPatCount(sdcBusiQcTriggeredEntity.getPatcount());
            analysisSdsPortalVo.setIds(String.valueOf(sdcBusiQcTriggeredEntity.getQcId()));
            analysisSdsPortalVo.setDescription(sdcBusiQcTriggeredEntity.getDetail());
            analysisSdsPortalVo.setPatName(sdcBusiQcTriggeredEntity.getAbbrev());
            analysisSdsPortalVo.setCount(sdcBusiQcTriggeredEntity.getCount());
            analysisSdsPortalVoList.add(analysisSdsPortalVo);
        }
        caseObj.put("qcCategory", analysisSdsPortalVoList);
        return caseObj;
    }

    /**
     * @Description: 查询质控触发数据列表
     * @return: JSONObject
     * @author: yanghangwei
     * @date:2023年8月10日 上午11:20:22
     */
    @Override
    public JSONObject selectTriggerCountByDate(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = new ArrayList<>();
        Date date = new Date();
        int Year = cn.hutool.core.date.DateUtil.year(date);
        int Month = cn.hutool.core.date.DateUtil.month(date) + 1;
        for (int i = 0; i < 9; i++) {
            //开始日期
            String startDate;
            //结束日期
            String endDate;
            if (Month>=10){
                endDate = Year+"-"+Month+"-01"+" 00:00:00";
            }else {
                endDate = Year+"-0"+Month+"-01"+" 00:00:00";
            }
            Month = Month - 1;
            if (Month <= 0){
                Month = 12;
                Year = Year - 1;
            }
            if (Month>=10){
                startDate = Year+"-"+Month+"-01"+" 00:00:00";
            }else {
                startDate = Year+"-0"+Month+"-01"+" 00:00:00";
            }
            int count = sdsQcincaseDataService.selectTriggerCountByDate(startDate, endDate, params);
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            analysisSdsPortalVo.setDate(Year+"年"+Month+"月");
            analysisSdsPortalVo.setCount(count);
            analysisSdsPortalVoList.add(0, analysisSdsPortalVo);
        }
        caseObj.put("triggerChart",analysisSdsPortalVoList);
        return caseObj;
    }

    /**
     * @Description: 查询医生质控数据列表
     * @return: JSONObject
     * @author: yanghangwei
     * @date:2023年8月10日 下午17:24:10
     */
    @Override
    public JSONObject selectDoctorChartData(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = new ArrayList<>();
        params.put("allEpi","selectAllEpiData");
        List<Map<String, Object>> doctorList = sdcHomeIndexService.selectDoctorChartData(params);
        for (Map<String, Object> doctorMap : doctorList) {
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            Integer count = ((Long) doctorMap.get("qcNum")).intValue();
            if (count.equals(0)){
                continue;
            }
            analysisSdsPortalVo.setDocName((String) doctorMap.get("doctorName"));
            analysisSdsPortalVo.setCount(count);
            analysisSdsPortalVoList.add(0,analysisSdsPortalVo);
            if (analysisSdsPortalVoList.size()>=10){
                break;
            }
        }
        caseObj.put("doctorChart",analysisSdsPortalVoList);
        return caseObj;
    }

    @Override
    public JSONObject selectQCDept(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = new ArrayList<>();
        List<CdcEpisodeEntity> cdcEpisodeEntities = sdsQcincaseDataService.selectQCDept(params);
        for (CdcEpisodeEntity cdcEpisodeEntitie : cdcEpisodeEntities){
            String deptName = cdcEpisodeEntitie.getAdmLocDesc();
            Long deptCount = cdcEpisodeEntitie.getDeptCount();
            analysisSdsPortalVoList.add(new AnalysisSdsPortalVo(deptName,deptCount));
        }
        caseObj.put("qcDept",analysisSdsPortalVoList);
        return caseObj;
    }

    @Override
    public JSONObject selectQcDetail(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<AnalysisSdsPortalVo> analysisSdsPortalVos = new ArrayList<>();
        // 类型转换
        String idStr =  params.get("id").toString();
        String qcDisName = params.get("qcDisName").toString();
        Long id = Long.valueOf(idStr);
        List<SdcQcEntity> sdcQcEntities = sdsQcincaseDataService.selectQcDetail(id);
        for (SdcQcEntity sdcQcEntity : sdcQcEntities){
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            analysisSdsPortalVo.setPatName(qcDisName);
            analysisSdsPortalVo.setDescription(sdcQcEntity.getQcDesc());
            analysisSdsPortalVo.setCount(sdcQcEntity.getCount());
            analysisSdsPortalVos.add(analysisSdsPortalVo);
        }
        caseObj.put("qcDetail",analysisSdsPortalVos);
        return caseObj;
    }

    @Override
    public JSONObject selectQCUseTime(Map<String, Object> params) {
        JSONObject caseObj = new JSONObject();
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = new ArrayList<>();
        List<Long> entityIds = sdsQcincaseService.selectEntity();
        a:for (Long entityId : entityIds){
            params.put("entityId", entityId);
            List<AnalysisSdsPortalVo> sdsPortalVoList = sdsQcincaseDataService.selectUseTime(params);
            if (sdsPortalVoList.isEmpty()){
                continue a;
            }
            Long sumMin = 0l;
            String s = sdsPortalVoList.get(0).getDescription();
            String c = sdsPortalVoList.get(0).getCode();
            List<Long> useTime = new ArrayList<>();
            b:for (AnalysisSdsPortalVo analysisSdsPortalVo : sdsPortalVoList){
                sumMin += analysisSdsPortalVo.getFillUseTime();
                useTime.add(analysisSdsPortalVo.getFillUseTime());
            }
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            String avgUseTime = StrUtil.deciFormatLong(sumMin, sdsPortalVoList.size());
            analysisSdsPortalVo.setDescription(s);
            analysisSdsPortalVo.setCode(c);
            analysisSdsPortalVo.setAvgUseTime(avgUseTime);
            analysisSdsPortalVo.setUseTime(useTime);
            analysisSdsPortalVoList.add(analysisSdsPortalVo);

        }
        caseObj.put("useTimeData", analysisSdsPortalVoList);
        return caseObj;
    }

    @Override
    public List<AnalysisSdsPortalVo> selectMrlistDataDetails(String idName, List<String> deptIds) {
        List<AnalysisSdsPortalVo> sdsPortalVoList;
        List<AnalysisSdsPortalVo> analysisSdsPortalVoList = sdsQcincaseDataService.selectMrlistDataDetails(idName, deptIds);
        sdsPortalVoList = this.handleMrlistCntDetails(analysisSdsPortalVoList);
        return sdsPortalVoList;
    }


    private void calSysSumChartData(String description, Map<String, AnalysisSdsPortalVo> calData, AnalysisSdsPortalVo analysisSdsPortalVo){
        Double costs = 0.0;
        if (!StringUtils.isEmpty(analysisSdsPortalVo.getCosts())){
            costs = analysisSdsPortalVo.getCosts();
        }
        if (CommonUtil.isEmpty(calData.get(description))){
            AnalysisSdsPortalVo analysisSdsPortalVo1 = new AnalysisSdsPortalVo();
            analysisSdsPortalVo1.setCosts(costs);
            analysisSdsPortalVo1.setCount(analysisSdsPortalVo.getCount());
            analysisSdsPortalVo1.setDays(analysisSdsPortalVo.getDays());
            calData.put(description, analysisSdsPortalVo1);
        }else {
            AnalysisSdsPortalVo analysisSdsPortalVo1 = calData.get(description);
            Double costs2 = 0.0;
            if (!StringUtils.isEmpty(analysisSdsPortalVo1.getCosts())){
                costs2 = analysisSdsPortalVo1.getCosts();
            }
            analysisSdsPortalVo1.setCosts(costs2 + costs);
            analysisSdsPortalVo1.setCount(analysisSdsPortalVo1.getCount() + analysisSdsPortalVo.getCount());
            analysisSdsPortalVo1.setDays(analysisSdsPortalVo1.getDays() + analysisSdsPortalVo.getDays());
        }

    }


    //报告的填报用时
    private Long handUseTime(Long inCaseId){
        //只取保存和提交操作所用时间
        List<String> status = Arrays.asList("Submit", "Save");
        List<SdsQcincaseOperlogEntity> sdsQcincaseOperlogEntities = sdsQcincaseOperlogService.selectUseTime(inCaseId, status);
        Long xUseTime = 0l;
        for (SdsQcincaseOperlogEntity sdsQcincaseOperlogEntity : sdsQcincaseOperlogEntities){
            //	没有记录操作开始日期，不计算用时
            if (CommonUtil.isEmpty(sdsQcincaseOperlogEntity.getOperStartDate())){
                continue ;
            }
            Long m = DateUtil.getDateCompare(sdsQcincaseOperlogEntity.getOperDate(), sdsQcincaseOperlogEntity.getOperStartDate(), "m");
            if (m > 60l){
                //	单次 用时超过一小时，不计为有效数据
                continue ;
            }
            xUseTime += m;
        }

        if (Objects.equals(0l, xUseTime)){
            //	如果没记录操作用时，默认10分钟（测试阶段用）
            xUseTime = 10l;
        }

        return xUseTime;
    }

    public class AnalysisData extends Thread{
        private Long entityId;
        private Map<String, Object> params;
        private Map<String, AnalysisSdsPortalVo> calData;
        private CountDownLatch countDownLatch;


        public AnalysisData(Long entityId, Map<String, Object> params, Map<String, AnalysisSdsPortalVo> calData, CountDownLatch countDownLatch){
            this.entityId = entityId;
            this.params = params;
            this.calData = calData;
            this.countDownLatch = countDownLatch;
        }
        public void run() {
            try {
                long start = System.currentTimeMillis();
                //消费
                AnalysisDataMain(entityId, params, calData);

                System.out.println(cn.hutool.core.util.StrUtil.format("entityId = {}, 用时：{}ms",entityId,System.currentTimeMillis() - start));

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();//计数器减1
            }
        }
    }

    public void AnalysisDataMain(Long entityId, Map<String, Object> params, Map<String, AnalysisSdsPortalVo> calData) throws Exception {
        handleSysSumChartData(entityId, params, calData);
        //这个时候处理完一个病例 多线程加锁
        synchronized (cur) {
            cur++;
        }
    }

    private void handleSysSumChartData(Long entityId, Map<String, Object> params, Map<String, AnalysisSdsPortalVo> calData) {
        AnalysisSdsPortalVo analysisSdsPortalVo = sdsQcincaseService.selectCostsAndDays(entityId, params);
        if (!StringUtils.isEmpty(analysisSdsPortalVo.getDescription())){
            String description = analysisSdsPortalVo.getDescription();
            switch (description){
                case "呼吸系统疾病/手术":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                case "神经系统疾病/手术":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                case "生殖系统疾病/手术":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                case "心血管系统疾病/手术":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                case "运动系统疾病/手术":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                case "肿瘤（手术治疗）":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                case "其他疾病/手术":
                    this.calSysSumChartData(description, calData, analysisSdsPortalVo);
                    break;
                default:
                    break;
            }
        }
    }

    private List<AnalysisSdsPortalVo> handleMrlistCntDetails(List<AnalysisSdsPortalVo> analysisSdsPortalVos){
        List<AnalysisSdsPortalVo> result = new ArrayList<>();
        Map<String, List<AnalysisSdsPortalVo>> collect = analysisSdsPortalVos.stream().collect(Collectors.groupingBy(AnalysisSdsPortalVo::getCode));
        for (String code : collect.keySet()){
            AnalysisSdsPortalVo analysisSdsPortalVo = new AnalysisSdsPortalVo();
            List<AnalysisSdsPortalVo> analysisSdsPortalVoList = collect.get(code);
            String ids = "";
            for (AnalysisSdsPortalVo sdsPortalVo : analysisSdsPortalVoList){
                ids += sdsPortalVo.getId() + ",";
            }
            analysisSdsPortalVo.setCode(code);
            analysisSdsPortalVo.setDescription(analysisSdsPortalVoList.get(0).getDescription());
            analysisSdsPortalVo.setCount(analysisSdsPortalVoList.size());
            analysisSdsPortalVo.setIds(ids);
            result.add(analysisSdsPortalVo);
        }
        return result;
    }

}
